{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 从 range开始"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for n in range(10,20):\n",
    "    for x in range(2,n):\n",
    "        if n % x == 0:\n",
    "            print(n,'equals',x,'乘以', n//x)\n",
    "            break\n",
    "    else:\n",
    "        print(n,\"是一个质数\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for n in range(1,10):\n",
    "    for x in range(2,5):\n",
    "        for i in range(1,5):\n",
    "            print('第三层循环 ',i)\n",
    "            break\n",
    "        else:\n",
    "            print('第三层循环_ ',i)\n",
    "    else:\n",
    "            print('第二层循环_ ',i)   \n",
    "else:\n",
    "            print('第一层循环_ ',i) "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##不能对同一参数多次赋值\n",
    "# 我试试MarkDownEditing的效果\n",
    "> 这个效果就是出来了是么\n",
    "> 一遍写一遍出效果是么\n",
    "> > 哈哈 [百度](www.baidu.com) 这个就是百度的超链接么\n",
    "* 你的意思是\n",
    "* 太帅了，我以后可以用vscode  写markdown了，哈哈\n",
    "* ~~要删除我么~~\n",
    "* ### 字体强调\n",
    "* **字体加粗**\n",
    "* __字体加粗__\n",
    "* *字体倾斜*\n",
    "---\n",
    "***\n",
    "___ \n",
    "* 上面是三种分隔符的写法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): \n",
    "    print(\"-- This parrot wouldn't\", action, end=' ')\n",
    "    print(\"if you put\", voltage, \"volts through it.\")\n",
    "    print(\"-- Lovely plumage, the\", type)\n",
    "    print(\"-- It's\", state, \"!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "parrot(voltage=1000000, action='VOOOOOM')\n",
    "parrot(action='VOOOOOM',voltage=100000)\n",
    "parrot('a million', 'bereft of life', 'jump')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "parrot() # required argument missing\n",
    "parrot(voltage=5.0, 'dead') # non-keyword argument after a keyword argument \n",
    "parrot(110, voltage=220) # duplicate value for the same argument \n",
    "parrot(actor='John Cleese') # unknown keyword argument"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*** 关键字参数要跟在位置参数后面 ***\n",
    "* 参数的顺序并不重要\n",
    "* 不能对同一个参数多次赋值"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> *args表示除了正常的正式的位置参数外，其他的所有位置参数；它是一个元祖（类似于java里的数组）\n",
    "\n",
    "> **keywards 表示除了正常的正式的关键字参数外，其他所有的关键字参数；它是一个字典（类似于java里的map）\n",
    "* 如果一个function里既有*args，又有**keywards，那么一定是*args在前，**keywards在后"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cheeseshop(kind, *args, **keywards):\n",
    "    print('Do you have any', kind, '?')\n",
    "    print('We are out of any ', kind)\n",
    "    print('*' * 40)\n",
    "\n",
    "    for arg in args:\n",
    "        print(arg)\n",
    "    print('-' * 40)\n",
    "\n",
    "    for kw in keywards:\n",
    "        print(kw, ':', keywards[kw])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cheeseshop('馒头', '土豆', 'tomato', one='rice',two='apple',fruit='banana')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 日期：2023_12_15\n",
    "> 上下文：列表作为stack ; 列表做为队列\n",
    "\n",
    "> 最新内容：列表推导式--一种更简单的列表创建方式\n",
    "\n",
    "* 最古老的方式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "arr = []\n",
    "for x in range(10):\n",
    "    arr.append(x**2)\n",
    "\n",
    "arr    "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 稍微高级些的方式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares = list(map(lambda x:x**2, range(10)))\n",
    "\n",
    "squares"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 最简洁的方式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares=[x**2 for x in range(10)]\n",
    "\n",
    "squares"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares1=[(x,y) for x in [1,2,4] for y in [2,5,7] if x!=y]\n",
    "\n",
    "squares1"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 上面的代码等价于下面的 繁琐的代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares1=[]\n",
    "for x in [1,2,4]:\n",
    "    for y in [2,5,7]:\n",
    "        if x != y:\n",
    "            squares1.append((x,y))\n",
    "\n",
    "squares1            "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 列表推导式 可以使用复杂的表达式和嵌套函数\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "vec=[[1,2,3],[2,3,4],[3,4,5]]\n",
    "[num for elem in vec for num in elem]\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 以下是错误的，注意跟下面正确的对比，观察"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "from math import pi\n",
    "[str(round(pi,i) for i in range(1,10))]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 以下是正确的，注意确认观察"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import pi\n",
    "[str(round(pi,i))for i in range(1,10)]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 嵌套式列表推导式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "metric = [\n",
    "    [1, 3, 5, 7],\n",
    "    [2, 4, 6, 8],\n",
    "    [0, 11, 13, 14]\n",
    "]\n",
    "\n",
    "[[row[i] for row in metric] for i in range(4)]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 上面的写法 ，翻译过来相当于下面的做法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "transposed = []\n",
    "\n",
    "for i in range(4):\n",
    "    transposed.append([row[i] for row in metric])\n",
    "\n",
    "transposed    "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 再翻译过来相当于下面的，更通俗,当然也是更繁琐的做法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "transposed = []\n",
    "\n",
    "for i in range(4):\n",
    "    transposed_row = []\n",
    "    for row in metric:\n",
    "        transposed_row.append(row[i])\n",
    "    transposed.append(transposed_row)\n",
    "    \n",
    "transposed    \n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 更简单，高级的方式，是使用内置函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list(zip(*metric))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* * * "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 下面学习【序列数据类型】\n",
    "* 列表和字符串在索引和切片上有很多相似性，所以我们管这种类型的数据结构 叫 【序列数据类型】\n",
    "   > 元组也是另一种【序列数字类型】\n",
    "   - 元组是由几个被逗号隔开的值组成\n",
    "   + 列表是由大括号组成"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = 12345, 45678, 'hello'\n",
    "list = [12345, 45678, 13579]\n",
    "\n",
    "print(t)\n",
    "print(list)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "+ 元组是immutable，不可变的，所以给其中的一个指定元素赋值是不被允许的；列表是可变的\n",
    "+ 元组里的元素，可以是不同类型；列表里的元素必须是相同类型\n",
    "+ 元组可以通过解包或者索引访问（如果是namedtuples，还可以通过属性访问）；列表可以通过解包、索引、迭代访问"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 元组的创建，可以带括号，也可以不带；一般，如果元组是更大的表达式的一部分，需要带上，这样也更容易看明白\n",
    "- 两个特殊的元组：空元组和只有一个元素的元组；空的元组，空括号即可表示；一个元素的元组，可以用不带括号的，一个元素 & 一个逗号表示\n",
    "- 括号里面 只放一个元素，文档说，这样的表达不够明确；具体怎么个不明确法，供后面发现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "empty_tuple = ()\n",
    "empty_tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "singleton_tuple = 'only_one',\n",
    "len(singleton_tuple)\n",
    "#singleton_tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "another_singleton_tuple = ('only_one',)\n",
    "len(another_singleton_tuple)\n",
    "# another_singleton_tuple"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 打包和解包\n",
    ">> t = 12345, 45678, 'hello' 这是一个打包的过程，打包进了一个元组\n",
    ">> x, y, z = t 这是一个解包的过程。将元组解包；文档上说，这个叫序列解包\n",
    ">> 函数的可变参数，*args， 其实就是元组打包和序列解包的组合实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = 12345, 45678, 'hello'\n",
    "x, y, z = t\n",
    "print(x)\n",
    "print(y)\n",
    "print(z)\n",
    "print(t)\n",
    "print(*t)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- - - "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 集合 - 不重复的无序元素集\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 用法：\n",
    "    >> 成员检查；\n",
    "    >> 消除重复成员；\n",
    "    >> 集合操作，比如合集，交集，差集，对称差分等数学操作；"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 要创建一个集合set，可以使用set()函数或者{}；只当集合元素不是空的时候，可以用花括号；空集合，不可使用花括号，因为{}表示的是一个空字典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "basket = {'apple', 'banana', 'orange', 'pear', 'apple'}\n",
    "\n",
    "print(basket)\n",
    "print('orange' in basket)\n",
    "\n",
    "a = set('abracadabra')\n",
    "b = set('alacazam')\n",
    "print(a)\n",
    "print(b)\n",
    "\n",
    "print(a - b)\n",
    "print(a | b)\n",
    "print(a ^ b)\n",
    "print(a & b)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 集合也支持推导式\n",
    "    * 下面的代码于 a - b 等价"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = set('abracadabra')\n",
    "b = set('alacazam')\n",
    "{x for x in a if a not in b}"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 字典\n",
    "- 就是java里的Map，健值对；key可以是任何不可变的对象\n",
    "- 空的字典使用{}创建；{}里放置以逗号分隔开的健值对，是对由内容的字典的初始化\n",
    "- list() 输出以插入先后为次序的健(key)的顺序列表；想要其他的顺序的key的列表，用sorted()方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tel = {'mamingchao':38, 'muxiaolin':36, 'mayuzhuo':7}\n",
    "print(tel)\n",
    "\n",
    "tel['liuyunli'] = 31\n",
    "del tel['mamingchao']\n",
    "print(tel)\n",
    "\n",
    "print(list(tel))\n",
    "\n",
    "print(sorted(tel))\n",
    "\n",
    "'mamingchao' in tel"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " * dict()字典构造方法可以直接根据健值对序列创建字典\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict([('mamingchao',38), ('muxiaolin',36), ('mayuzhuo',7)])"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "+ 当健是简单字符串时，通过关键字参数指定健值对更方便"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict(mamingchang = 38, muxiaolin = 36, mayuzhuo = 7)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 通过推导式，创建字典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "{x:x**2 for x in range(2,8)}"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- - -"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 字典和序列 循环遍历的技巧"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 字典的遍历\n",
    "    - 使用items() 可以将字典的健和值都取出来"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict_ = dict(mamingchang = 38, muxiaolin = 36, mayuzhuo = 7)\n",
    "\n",
    "for k, v in dict_.items():\n",
    "    print(k, v)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 序列的遍历\n",
    "    - 使用enumerate()可以取出序列的索引和对应的value\n",
    "    + 如果想要指定一个顺序循环，使用sorted()函数，它可以在不动原来序列的基础上返回一个新的排好序的序列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_ = [12345, 45678, 13579]\n",
    "\n",
    "for i, v in enumerate(list_):\n",
    "    print(i, v)\n",
    "\n",
    "for e in sorted(list_):\n",
    "    print(e) "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 文档里，关于上述第二点，使用sorted()生成一个新的、有顺序的序列进行循环的时候，是这样写的：\n",
    "    - for e in sorted(set(list_)):\n",
    "    -   print(e) \n",
    "    - __上面试了，不用set()函数也可以；这部分后面再研究吧__"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- zip 函数，之前在讲 嵌套的列表推导式时讲过\n",
    "    + 二维序列，矩阵反转的时候，用过\n",
    "    + 看来，zip比较适合 做二维序列矩阵反转"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "questions = ['name', 'quest', 'favorite color']\n",
    "answers = ['mamingchao', 'keep learning, being better', 'blue']\n",
    "\n",
    "for q, a in zip(questions, answers):\n",
    "    print('What is your {0}? It is {1}.'.format(q, a))\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 条件控制\n",
    "- in 和 not in 比较元素在不在序列i， is 和not is 比较是不是同一个对象， 均为比较运算符\n",
    "- 所有运算符的 优先级相同，且优先级低于 数值运算符\n",
    "- and or not 为比尔运算符， 比较运算符可以于比尔运算符组合使用\n",
    "- 布尔运算符中 not的优先级最高，or优先级最低\n",
    "- 布尔运算符的优先级，都低于比较运算符\n",
    "- 根其他开发语言应该一样，至少根java一样；即布尔运算符中的and 和 or 也成为【短路运算符】，从左至右的解析，一旦解析到确定的结果，就不再继续解析"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 比较运算符，可以这样写：表示 a 小于 b 且 b等于 c；文档上说（比较运算符可以比较？）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b, c = 3, 5, 6\n",
    "\n",
    "a < b == c"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 也可以把比较操作或者逻辑表达式的结果，赋值给一个变量，例如下面"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "string1, string2, string3 = '', 'mamingchao', ''\n",
    "not_null = string1 or string2 or string3\n",
    "not_null"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 注意有一点： python不允许在表达式内部赋值；这一点与 C语言不太一致"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 比较序列和其他类型\n",
    "    - 序列对比，序列元素对象可以与相同类型的对象比较，使用字典序列顺序比较\n",
    "    - 先比对序列第一个元素；如果第一个元素相同，再比较第二个，直到有一个序列被耗尽（没有更多元素可以对比）\n",
    "    - 如果比对的两个元素本身就是序列，递归进行字典序列对比\n",
    "    - 如果两个序列中所有元素都相等，则两个序列就相等\n",
    "    - 序列的子序列 小于 父序列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print((1, 2, 3) < (1, 2, 4))\n",
    "print([1, 2, 3] < [1, 2, 4])\n",
    "print('ABC' < 'C' < 'Pascal' < 'Python')\n",
    "print((1, 2, 3, 4) < (1, 2, 4))\n",
    "print((1, 2) < (1, 2, -1))\n",
    "print((1, 2, 3) == (1.0, 2.0, 3.0))\n",
    "print((1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4))\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- - - \n",
    "* * * "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### module 模块"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- python 的代码编写的文件，成为python 脚本，扩展名.py\n",
    "- 一个python文件过于冗长，会按照业务或者功能拆分出几个文件，这就叫模块\n",
    "- 在一个模块内部，一个模块名（字符串）可以通过全局变量__name__获得\n",
    "- 比如我们创建了一个 名称为 fibol.py的一个python脚本文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Fibonacci numbers module\n",
    "def fib(n): # write Fibonacci series up to n a, b = 0, 1\n",
    "    while a < n:\n",
    "        print(a, end=' ') \n",
    "        a, b = b, a+b\n",
    "    print()\n",
    "\n",
    "def fib2(n): # return Fibonacci series up to n \n",
    "    result = []\n",
    "    a, b = 0, 1 \n",
    "    while a < n:\n",
    "        result.append(a)\n",
    "        a, b = b, a+b \n",
    "    return result"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 我如果要使用这两个方法，可以导入这个模块\n",
    "- 可以在python 解释器里 import fibo\n",
    "- 在当前的【符号表】中，记录了 fibo这个模块名，并不会记录fibo里面的两个函数\n",
    "- 所以，使用fibo.fib 来使用函数\n",
    "- 如果会经常使用fib这个函数，也可以把这个函数赋值给一个局部变量 my_fib = fibo.fib\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import fibo\n",
    "from fibo import fib, fib2"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 模块中可以包含一些可执行的语句和函数，用来初始化模块；当模块被首次import/当脚本执行的时候，才会执行到\n",
    "- 每个module都有自己的私有符号表，用于记录模块自己的所有函数/变量的全局符号表。\n",
    "- 模块作者可以在自己模块内定义全局符号，而不必担心与使用模块的用户定义的全局符号发生冲突\n",
    "- 被导入的模块名存放在 调用者的全局符号表中"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> * 在导入其他模块具体方法的时候，尽量使用 from fibo import fib, fib2, 而不是 from fibo import *\n",
    "> * 这样会引入所有除 __开头的名称，可能会覆盖我们自己定义的名称\n",
    "> * 另外，这个 import *， 我们也不清楚，具体导入了什么名称，代码可读性不好\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> - 还可以给导入的方法重命名\n",
    "> - from fibo import fib as fibonacci"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 特别说明\n",
    "> - 出于对效率的考虑，每个模块在每个解释器的会话中只会初始化一次；如果被导入的模块有调整和改动，则需要重新加载，重启解释器；\n",
    "> - 或者 我们也可以使用内置方法，强制重新加载；\n",
    ">>- import importlib\n",
    ">>- importlib.reload(moduleName)      \n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 7.1.1 格式化字符串文字"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 格式化输出的几种方式\n",
    "    - 格式化字符串字面值， 也称 f-字符串\n",
    "        - 字符串前加 f 或者F\n",
    "        - 字符串里的表达式 用大括号括住 ，{expression}\n",
    "        - 可选的格式说明可以跟在表达式的后面"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import pi\n",
    "print(f'The value of pi approximately is {pi:.9f}')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 在表达式后面设置一个整数的格式，可以为该字段设置上最小字符宽度；这样使列对齐的时候很有用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "table = dict(mamingchao= 38, muxiaolin = 36, mayuzhuo = 6)\n",
    "for name, age in table.items():\n",
    "    print(f'{name:10} ==> {age :10d}')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 还有其他修饰符可以用于在格式化之前，做转化\n",
    "- !s 应用 str()\n",
    "- !a 应用 ascii()\n",
    "- !r 应用 repr()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "animals = 'eels'\n",
    "\n",
    "print(f'My hovercraft is full of {animals} .')\n",
    "print(f'My hovercraft is full of {animals!r} .')\n",
    "print(f'My hovercraft is full of {animals!a} .')\n",
    "print(f'My hovercraft is full of {animals!r:10} .')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- str.format()\n",
    "    - 前面是带占位符的字符串，format里传入位置或者关键字参数\n",
    "    - 这里的位置和关键字参数的要求，与函数的参数规范要求一致\n",
    "    - 如果有一个很长的字符串需要格式化，建议使用关键字参数而不是位置参数\n",
    "    - 如果format参数太多，可以把所有参数放入字典中，给format参数传入一个字典 \n",
    "    - 使用字典的时候，可以使用解包\n",
    "    - 这一招，根内置函数vars(),返回包含所有局部变量的字典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "We are the knights who say \"Ni!\"\n",
      "We are the knights who say \"Ni!\"\n",
      "We are the Ni who say \"knights!\"\n",
      "We are the gentelman who say \"Hi!\"\n",
      "We are the gentelman who say \"Hi!\"\n",
      "Jack;4098, Dcab;8637678, Sjoerd;4127\n",
      "Jack;4098, Dcab;8637678, Sjoerd;4127\n"
     ]
    }
   ],
   "source": [
    "print('We are the {} who say \"{}!\"'.format('knights', 'Ni'))\n",
    "print('We are the {0} who say \"{1}!\"'.format('knights', 'Ni'))\n",
    "print('We are the {1} who say \"{0}!\"'.format('knights', 'Ni'))\n",
    "print('We are the {role} who say \"{words}!\"'.format(role = 'gentelman', words = 'Hi'))\n",
    "print('We are the {0} who say \"{words}!\"'.format('gentelman', words = 'Hi'))\n",
    "# print('We are the {role} who say \"{1}!\"'.format(role = 'gentelman','Hi'))\n",
    "\n",
    "table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}\n",
    "print('Jack;{0[Jack]:d}, Dcab;{0[Dcab]:d}, Sjoerd;{0[Sjoerd]:d}'.format(table))\n",
    "print('Jack;{Jack:d}, Dcab;{Dcab:d}, Sjoerd;{Sjoerd:d}'.format(**table))\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 手动格式化字符串\n",
    "    - str.rjust() 通过左侧填充空格对给定宽度的字段中的字符串进行右对齐\n",
    "    - str.ljust() 通过右侧填充空格对给定宽度的字段中的字符串进行左对齐\n",
    "    - str.center() 通过两侧填充空格对给定宽度的字段中的字符串进行居中对齐\n",
    "    - str.zfill() 对数字字符串的左侧填充零；方法可识别正负符号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1  1   1   \n",
      "2  4   8   \n",
      "3  9   27  \n",
      "4  16  64  \n",
      "5  25  125 \n",
      "6  36  216 \n",
      "7  49  343 \n",
      "8  64  512 \n",
      "9  81  729 \n",
      "10 100 1000\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'-003.14'"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for i in range(1,11):\n",
    "    print(str(i).ljust(2), str(i*i).ljust(3), str(i*i*i).ljust(4))\n",
    "\n",
    "'12'.zfill(5)\n",
    "'-3.14'.zfill(7)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- % 符号也可以用作字符串格式化；% 左侧的字符串看作一个很像printf风格的字符串，符号右侧是要替换的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The value of pi approximately is 3.1415927\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "print(\"The value of pi approximately is %2.7f\" % math.pi)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- - - \n",
    "### 每日一道题"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "～～ 无重复字符的最长字串 ～～"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_ = ['a', 'b', 'c', 'a', 'b', 'b', 'd', 'b', 'c']\n",
    "\n",
    "sub_list=[]\n",
    "longestSubstringFirstLetter=''\n",
    "longestSubstringLetterNum = 0\n",
    "currentSubstringLetter=''\n",
    "currentSubstringLetterIndex = 0\n",
    "\n",
    "for i, v in enumerate(list_):\n",
    "    currentSubstringLetter = v\n",
    "    for j in range( currentSubstringLetterIndex + 1, len(list_)):\n",
    "        sub_list.append(list_[j - 1])\n",
    "        currentSubstringLetterIndex = j \n",
    "        if list_[j] != currentSubstringLetter and list_[j] not in sub_list:\n",
    "            pass\n",
    "        elif(j - i > longestSubstringLetterNum):\n",
    "            longestSubstringLetterNum = j - i\n",
    "            longestSubstringFirstLetter = currentSubstringLetter\n",
    "            break\n",
    "    \n",
    "# element_map = {v:[].append(i) for i, v in enumerate(list_)}\n",
    "print(longestSubstringLetterNum, longestSubstringFirstLetter)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
